package com.java.netty.nio.netty.simple;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;

/**
 * @Author: Dgg
 * @Date: 2021/12/11 22:02
 */
public class NettyServer {

	public static void main(String[] args) throws InterruptedException {

		//创建 BossGroup 和 WorkerGroup
		//1.创建两个线程组
		//2.bossGroup 只处理链接请求,真正的与客户端业务交互会交给 workerGroup 完成
		//3.两个都是无限循环
		//4.boosGroup和workerGroup的子线程数量默认是你的cpu核数*2
		EventLoopGroup boosGroup = new NioEventLoopGroup();
		//workerGourp 采用轮询分配任务
		EventLoopGroup workerGroup = new NioEventLoopGroup();

		try {
			//创建服务器端的启动对象，配置参数
			ServerBootstrap bootstrap = new ServerBootstrap();

			//使用链式编程进行设置
			bootstrap.group(boosGroup, workerGroup)//设置两个线程组
					.channel(NioServerSocketChannel.class)//使用NioServerSocketChannel 作为服务器通道实现
					.option(ChannelOption.SO_BACKLOG, 128)//设置线程队列得到的链接个数
					.childOption(ChannelOption.SO_KEEPALIVE, true)//设置保持活动连接状态
					.childHandler(new ChannelInitializer<SocketChannel>() {//创建一个通道初始化对象
						//向给pipeline 设置处理器
						@Override
						protected void initChannel(SocketChannel socketChannel) throws Exception {
							ChannelPipeline pipeline = socketChannel.pipeline();
							//可以使用一个集合管理socketChannel,再推送业务时候，可
							// 以将业务放到各个channel对应的NIOEventLoop 的taskQueue 或者scheduleTaskQueue
							System.out.println("客户端socketChannel===HashCode：" + socketChannel.hashCode());
							pipeline.addLast(new NettyServerHandler());
						}
					});//给我们的workerGroup 的某一个EventGroup 对应的管道设置处理器
			System.out.println("......The NIO server is read.........");
			//绑定一个端口 并且 同步，生成了一个 channelFutura 对象
			//启动服务器 并绑定端口
			ChannelFuture cf = bootstrap.bind(6668).sync();
			//对关闭通道进行监听
			ChannelFuture sync1 = cf.channel().closeFuture().sync();
		} catch (InterruptedException e) {
			e.printStackTrace();
		} finally {
			boosGroup.shutdownGracefully();
			workerGroup.shutdownGracefully();
		}
	}
}
